package com.djmw.mouse.web.member;

import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.validation.Valid;
import javax.validation.Validator;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.modules.web.Servlets;

import com.djmw.mouse.entity.Cv;
import com.djmw.mouse.entity.CvLang;
import com.djmw.mouse.entity.CvWorkingExperience;
import com.djmw.mouse.entity.MemberUser;
import com.djmw.mouse.service.CvLangService;
import com.djmw.mouse.service.CvService;
import com.djmw.mouse.service.account.MemberAccountService;
import com.djmw.mouse.service.account.ShiroDbRealm.ShiroUser;
import com.djmw.mouse.service.constants.Constants;
import com.google.common.collect.Maps;

/**
 * 简历管理的Controller, 使用Restful风格的Urls:
 * 
 * List page : GET /member/cv <br>
 * Create page : GET /member/cv/create <br>
 * Create action : POST /member/cv/create <br>
 * Update page : GET /member/cv/update/{id} <br>
 * Update action : POST /member/cv/update <br>
 * Delete action : GET /member/cv/delete/{id} <br>
 * 
 * @author michael
 */

@Controller
@RequestMapping(value = "/member/cv")
public class CvController {

    private static Map<String, String> sortTypes = Maps.newLinkedHashMap();
    static {
        sortTypes.put("auto", "自动");
        sortTypes.put("name", "部门名称");
    }

    @Autowired
    private CvService cvService;
    @Autowired
    private CvLangService cvLangService;
    @Autowired
    private MemberAccountService memberAccountService;
    @Autowired
    private Validator validator;

    @RequestMapping(value = "")
    public String list(Model model, ServletRequest request) {
        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "search_");
        Page<Cv> cvs = cvService.getMemberCv(getCurrentUser().getId(), false);

        model.addAttribute("cvs", cvs);
        model.addAttribute("sortType", "auto");
        model.addAttribute("sortTypes", sortTypes);
        // 将搜索条件编码成字符串，用于排序，分页的URL
        model.addAttribute("searchParams", Servlets.encodeParameterStringWithPrefix(searchParams, "search_"));

        return "member/cv-list";
    }

    @RequestMapping(value = "create/{lang}", method = RequestMethod.GET)
    public String createForm(@PathVariable("lang") Integer lang, Model model) {
        Cv cv = new Cv();
        cv.setMemberUser(getCurrentUser());
        cv.setCurLang(lang);
        cv.setCurCvLang(new CvLang(cv, lang));
        model.addAttribute("cv", cv);
        addFormConstants(model);
        model.addAttribute("action", "create");
        return "member/cv-form";
    }

    @RequestMapping(value = "create", method = RequestMethod.POST)
    public String create(@Valid @ModelAttribute("preloadCV") Cv cv, Boolean _baseInfoUpdated,
            RedirectAttributes redirectAttributes) {
        cv.getCurCvLang().normalize();
        cvService.saveCv(cv);
        // cvLangService.saveCvLang(cv.getCurCvLang());
        if (Boolean.TRUE.equals(_baseInfoUpdated)) {
            MemberUser user = getCurrentUser();
            user.updateBaseInfo(cv.getMemberUser());
            memberAccountService.updateUser(user);
        }
        redirectAttributes.addFlashAttribute("message", "创建简历成功");
        return "redirect:/member/cv/";
    }

    @RequestMapping(value = "{id}/update/{lang}", method = RequestMethod.GET)
    public String updateForm(@PathVariable("id") Long id, @PathVariable("lang") Integer lang, Model model) {
        Cv cv = cvService.getCv(id);
        cv.setCurLang(lang);
        if (cv.getCurCvLang() == null) {
            cv.setCurCvLang(new CvLang(cv, lang));
        }
        model.addAttribute("cv", cv);
        addFormConstants(model);
        model.addAttribute("action", "update");
        return "member/cv-form";
    }

    @RequestMapping(value = "update", method = RequestMethod.POST)
    public String update(@Valid @ModelAttribute("preloadCV") Cv cv, Boolean _baseInfoUpdated,
            RedirectAttributes redirectAttributes, ServletRequest request) {
        Enumeration<?> e1 = request.getParameterNames();
        Logger.getLogger(CvController.class).info("------Start--------");
        while (e1.hasMoreElements()) {
            String name = (String) e1.nextElement();
            String value = request.getParameter(name);
            Logger.getLogger(CvController.class).info(name + ":" + value);
        }
        Logger.getLogger(CvController.class).info("------End--------");
        cv.getCurCvLang().normalize();
        // update member user headline
        List<CvWorkingExperience> cvWorkings = cv.getCurCvLang().getCvWorkingExperience();
        if (cvWorkings != null && cvWorkings.size() > 0) {
            CvWorkingExperience cvWorking = cvWorkings.get(0);
            String headline = cvWorking.getPosition()
                    + (cvWorking.getDepartment() == null ? "" : (" - " + cvWorking.getDepartment())) + " @ "
                    + cvWorking.getCompany();
            cv.getMemberUser().setHeadline(headline);
        }
        cvService.saveCv(cv);
        // cvLangService.saveCvLang(cv.getCurCvLang());
        if (Boolean.TRUE.equals(_baseInfoUpdated)) {
            MemberUser user = getCurrentUser();
            MemberUser user2 = memberAccountService.getUser(user.getId());
            user2.updateBaseInfo(cv.getMemberUser());
            memberAccountService.updateUser(user2);
        }
        redirectAttributes.addFlashAttribute("message", "更新简历成功");
        return "redirect:/member/cv/";
    }

    @RequestMapping(value = "delete/{id}")
    public String delete(@PathVariable("id") Long id, RedirectAttributes redirectAttributes) {
        cvService.deleteCv(id);
        redirectAttributes.addFlashAttribute("message", "删除简历成功");
        return "redirect:/member/cv/";
    }

    /**
     * 使用@ModelAttribute, 实现Struts2
     * Preparable二次部分绑定的效果,先根据form的id从数据库查出CV对象,再把Form提交的内容绑定到该对象上。
     * 因为仅update()方法的form中有id属性，因此本方法在该方法中执行.
     */
    @ModelAttribute("preloadCV")
    public Cv getCv(@RequestParam(value = "id", required = false) Long id,
            @RequestParam(value = "curLang", required = false) Integer curLang) {
        if (id == null && curLang == null) {
            return null;
        }
        Cv cv = id == null ? new Cv() : cvService.getCv(id);
        if (curLang != null) {
            cv.setCurLang(curLang);
            if (cv.getCurCvLang() == null) {
                cv.setCurCvLang(new CvLang(cv, curLang));
            }
        }
        return cv;
    }

    public MemberUser getCurrentUser() {
        ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
        return (MemberUser) user.getUser();
    }

    private void addFormConstants(Model model) {
        model.addAttribute("_provinces", Constants.PROVINCES);
        model.addAttribute("_cities", Constants.CITIES);
        // model.addAttribute("languages", Constants.LANGUAGES);
        // model.addAttribute("proficiencys", Constants.PROFICIENCYS);
        // model.addAttribute("educations", Constants.EDUCATIONS);
        model.addAttribute("_workingYears", Constants.WORKING_YEARS_MEMBER);
        model.addAttribute("_certTypes", Constants.CERT_TYPES);
        model.addAttribute("_salaryRanges", Constants.YEARLY_SALARY_RANGES);
        model.addAttribute("_currencies", Constants.CURRENCIES);
        model.addAttribute("_situations", Constants.SITUATIONS);
        model.addAttribute("_countries", Constants.COUNTRIES);
        model.addAttribute("_marriageStatus", Constants.MARRIAGE_STATUS);
        model.addAttribute("_politicalStatus", Constants.POLITICAL_STATUS);
        model.addAttribute("_degrees", Constants.EDUCATIONS);
        model.addAttribute("_companySizes", Constants.COMPANY_SIZES);
        model.addAttribute("_companyTypes", Constants.COMPANY_TYPES);
        // model.addAttribute("majors", Constants.MAJORS);
        // model.addAttribute("jobTypes", Constants.JOB_TYPES);
        // model.addAttribute("lang", CvLang.LANG_CHINESE);
    }
}
